local json = require("json")

local deviceNameMapping = {
    ["0xEC1BBDFFFEBAC87C-3"] = "书房灯",
    ["0xEC1BBDFFFEBAC87C-2"] = "客厅主灯",
    ["0xEC1BBDFFFEBAC87C-1"] = "客厅灯带",
    ["0x588E81FFFEB3535C-2"] = "餐厅主灯",
    ["0x588E81FFFEB3535C-3"] = "餐厅射灯",

    --["0x84FD27FFFE8E1746-1"] = "客厅射灯",

    ["0xEC1BBDFFFEBAC639-1"] = "主卧主灯",
    ["0xEC1BBDFFFEBAC639-2"] = "主卧过道灯",
    ["0x588E81FFFEB1B363-1"] = "主卧左床头灯",
    ["0x588E81FFFEB1BB47-1"] = "主卧右床头灯",
    ["0xEC1BBDFFFEBAC639-3"] = "主卧灯带",
}

local command_map = {
    ["0xEC1BBDFFFEBAC87C-3"] = "send 0x6A2D 1 3",
    ["0xEC1BBDFFFEBAC87C-2"] = "send 0x6A2D 1 2",
    ["0xEC1BBDFFFEBAC87C-1"] = "send 0x6A2D 1 1",
    ["0x588E81FFFEB3535C-2"] = "send 0x532A 1 2",
    ["0x588E81FFFEB3535C-3"]="send 0x532A 1 3", --餐厅射灯

    ["0xEC1BBDFFFEBAC639-1"] = "send 0x7887 1 1",
    ["0xEC1BBDFFFEBAC639-2"] = "send 0x7887 1 2",
    ["0x588E81FFFEB1B363-1"] = "send 0x42B2 1 1", --主卧左床头灯
    ["0x588E81FFFEB1BB47-1"] = "send 0xBD68 1 1", -- 主卧右床头灯
    ["0xEC1BBDFFFEBAC639-3"] = "send 0x7887 1 3", --主卧灯带

    --["send 0x1028 1 1"] = 'light3', --过道灯
    --["send 0xF25D 1 1"] = "kt_sd", --客厅射灯

}

function isMapEmpty(map)
    for _, _ in pairs(map) do
        return false
    end
    return true
end
-- decode 请求数据解码
function decode(raw)
    local data = json.decode(raw)
    local payload = json.decode(data["payload"])
    local devices = {}
    local device = {}

    --if payload["clusterId"] == "0x0006" then
    --    return "[]"
    --end

    -- 控制响应
    if data.topic == "gw/804B50FFFEE7BB91/zclresponse" and payload["commandId"] == "0x0A" then
        key = payload["deviceEndpoint"]["eui64"] .. "-" .. payload["deviceEndpoint"]["endpoint"]
        name = deviceNameMapping[key]
        if name == nil then
            return "[]"
        end
        device['id'] = key;

        if payload["commandData"] == "0x00001000" then
            -- 灯状态：关
            device['values'] = {
                { ["name"] = 'onOff', ["value"] = '0' },
            }
        elseif payload["commandData"] == "0x00001001" then
            -- 灯状态：开
            device['values'] = {
                { ["name"] = 'onOff', ["value"] = '1' },
            }
        elseif string.sub(payload['commandData'], 1, 8) == "0x000020" then
            --  射灯亮度
            hex = tonumber(string.sub(payload['commandData'], 9, -1), 16)
            device['values'] = {
                { ["name"] = 'brightness', ["value"] = math.floor((hex / 255) * 100 + 0.5) },
            }
        end

        device["events"] = {
            {
                ["code"] = "deviceDiscover",
                ["value"] = {
                    ["modelKey"] = "smarthome_light",
                    ["device"] = {
                        ["id"] = key,
                        ["description"] = name,
                    }
                }
            }
        }
        table.insert(devices, device)
        return json.encode(devices)
    end

    -- 状态同步
    if data.topic == "gw/804B50FFFEE7BB91/zclresponse" and payload["attributeId"] ~= nil then
        key = payload["deviceEndpoint"]["eui64"] .. "-" .. payload["deviceEndpoint"]["endpoint"]
        name = deviceNameMapping[key]
        if name == nil then
            return "[]"
        end
        device['id'] = key;

        -- 开关
        if payload["attributeId"] == "0x0000" and payload["attributeDataType"] == "0x10" then
            if payload["attributeBuffer"] == "0x00" then
                device['values'] = {
                    { ["name"] = 'onOff', ["value"] = '0' },
                }
            else
                if payload["attributeBuffer"] == "0x0A" then
                    device['values'] = {
                        { ["name"] = 'onOff', ["value"] = '1' },
                    }
                end
            end

            device["events"] = {
                {
                    ["code"] = "deviceDiscover",
                    ["value"] = {
                        ["modelKey"] = "smarthome_light",
                        ["device"] = {
                            ["id"] = key,
                            ["description"] = name,
                        }
                    }
                }
            }
            table.insert(devices, device)
            return json.encode(devices)
        end
    end

    if data.topic ~= 'gw/804B50FFFEE7BB91/commands' then
        return '[]'
    end

    for i, command in pairs(payload['commands']) do
        if command['commandcli'] == nil then
            break
        end
        key = command_map[command['commandcli']]
        if key ~= nil then
            device['id'] = key
        end

        if string.sub(command['commandcli'], 1, 10) == 'raw 0x0008' then
            hex = tonumber(string.sub(command['commandcli'], 19, 20), 16)
            device['values'] = {
                { ["name"] = 'brightness', ["value"] = math.floor((hex / 255) * 100 + 0.5) },
            }
        elseif string.sub(command['commandcli'], -2) == '0}' then
            device['values'] = {
                { ["name"] = 'onOff', ["value"] = '0' },
            }
        elseif string.sub(command['commandcli'], -2) == '1}' then
            device['values'] = {
                { ["name"] = 'onOff', ["value"] = '1' },
            }
        end
    end
    table.insert(devices, device)
    return json.encode(devices)
end

function encode(device_name, rw, points)
    if rw == "read" then
        print("unsupport read...")
        return "{}"
    end
    if not device_name then
        print("device name not found")
        return "{}"
    end

    local result = {

    }

    local commandCli = command_map[device_name]
    if commandCli == nil then
        print("commandCli not found, device: " .. device_name)
        return "{}"
    end

    for _, command in pairs(points) do
        local pointName = command['name']
        local value = command['value']
        -- 开关
        local commands = {}
        if pointName == 'onOff' then
            if value == 0 then
                table.insert(commands, {
                    ["commandcli"] = "raw 0x0006 {010000}",
                    ["postDelayMs"] = 0
                })
            else
                table.insert(commands, {
                    ["commandcli"] = "raw 0x0006 {010001}",
                    ["postDelayMs"] = 0
                })
            end
            table.insert(commands, {
                ["commandcli"] = commandCli,
                ["postDelayMs"] = 300
            })
            table.insert(result, {
                ["topic"] = "gw/804B50FFFEE7BB91/commands",
                ["payload"] = json.encode({ ["commands"] = commands })
            })
        end

        if pointName == 'brightness' then
            val = value * 255 / 100
            table.insert(commands, {
                ["commandcli"] = "raw 0x0008 {018804" .. string.format("%02X", val) .. "0000}",
                ["postDelayMs"] = 0
            })
            table.insert(result, {
                ["topic"] = "gw/804B50FFFEE7BB91/commands",
                ["payload"] = json.encode({ ["commands"] = commands })
            })
        end
    end

    return json.encode(result)
end